package com.yohann.aliyun_service.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.vod.model.v20170321.DeleteVideoRequest;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoRequest;
import com.aliyuncs.vod.model.v20170321.GetPlayInfoResponse;
import com.yohann.aliyun_service.service.AliyunService;
import com.yohann.aliyun_service.utils.ConstantConfig;
import com.yohann.aliyun_service.utils.RandomUtil;
import com.yohann.base.exception.IEnglishException;
import com.yohann.utils.result.Result;
import org.apache.commons.lang.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static com.yohann.aliyun_service.utils.AliyunVodSDKUtils.initVodClient;

/**
 * <p>
 * 阿里云服务业务实现
 * </p>
 *
 * @author Yohann
 * @since 2020/10/19 16:44
 */
@Service
public class AliyunServiceImpl implements AliyunService {
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * 上传照片
     *
     * @param file
     * @return
     */
    @Override
    public String uploadFileImage(MultipartFile file) {
        String endpoint = ConstantConfig.END_POIND;
        String accessKeyId = ConstantConfig.END_KEYID;
        String accessKeySecret = ConstantConfig.END_KEYSECRET;
        String bucketName = ConstantConfig.END_BUCKETNAME;

        //输入流
        InputStream inputStream = null;

        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

            //当前文件名
            String fileName = file.getOriginalFilename();
            System.out.println(fileName);
            fileName = fileName.substring(fileName.lastIndexOf("."));

            //随机生成文件名
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");

            //获取日期
            String datePath = new DateTime().toString("yyyy/MM/dd");

            //最终文件名
            fileName = datePath + "/" + uuid + fileName;

            //获取流数据
            inputStream = file.getInputStream();

            //提交
            ossClient.putObject(bucketName, fileName, inputStream);

            // 关闭OSSClient。
            ossClient.shutdown();

            //返回URL
            return "https://" + bucketName + "." + endpoint + "/" + fileName;
        } catch (IOException e) {
            throw new IEnglishException(20001, "上传失败");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 上传视频
     *
     * @param file
     */
    @Override
    public String uploadVideo(MultipartFile file) {
        //视频id
        String id = null;
        //输入流
        InputStream inputStream = null;

        try {
            //获取后缀名
            String fileName = file.getOriginalFilename();
            String title = Objects.requireNonNull(fileName).substring(0, fileName.lastIndexOf("."));

            //获取视频输入流
            inputStream = file.getInputStream();

            //创建oss存储请求
            UploadStreamRequest request = new UploadStreamRequest(ConstantConfig.END_KEYID, ConstantConfig.END_KEYSECRET, title, fileName, inputStream);

            //请求上传视频
            UploadVideoImpl uploadVideo = new UploadVideoImpl();
            UploadStreamResponse response = uploadVideo.uploadStream(request);

            //获取视频id
            if (response.isSuccess()) {
                id = response.getVideoId();
            } else {
                id = response.getVideoId();
            }

            return id;
        } catch (IOException e) {
            throw new IEnglishException(20001, "上传失败");
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 获取视频url
     *
     * @param id
     * @return
     */
    @Override
    public String getVideoUrl(String id) {
        String url = null;

        try {
            //创建client
            DefaultAcsClient client = initVodClient(ConstantConfig.END_KEYID, ConstantConfig.END_KEYSECRET);

            //创建获取信息的请求
            GetPlayInfoRequest request = new GetPlayInfoRequest();
            request.setVideoId(id);
            GetPlayInfoResponse response = client.getAcsResponse(request);
            List<GetPlayInfoResponse.PlayInfo> playInfoList = response.getPlayInfoList();

            //播放地址
            url = playInfoList.get(0).getPlayURL();
            client.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return url;
    }

    /**
     * 删除视频
     *
     * @param id
     * @return
     */
    @Override
    public void deleteVideo(String id) {
        try {
            //创建client
            DefaultAcsClient client = initVodClient(ConstantConfig.END_KEYID, ConstantConfig.END_KEYSECRET);

            //创建删除请求
            DeleteVideoRequest request = new DeleteVideoRequest();
            request.setVideoIds(id);

            //执行删除操作
            client.getAcsResponse(request);
            client.shutdown();
        } catch (ClientException e) {
            throw new IEnglishException(20001, "视频删除失败");
        }
    }

    /**
     * 发送验证码
     *
     * @param phone
     * @return
     */
    @Override
    public Result sendCode(String phone) {
        //在redis中获取验证码
        String code = redisTemplate.opsForValue().get(phone);

        //判断是否一分钟内已发送过
        if (!StringUtils.isEmpty(code)) {
            return Result.ok().message("验证码已发送，请1分钟后再试！");
        }

        //随机生成验证码
        code = RandomUtil.getRandomCode();
        Map<String, Object> param = new HashMap<>();
        param.put("code", code);

        boolean isSend = send(param, phone);
        if (isSend) {
            //在redis中存放验证码
            redisTemplate.opsForValue().set(phone, code, 3, TimeUnit.MINUTES);
            System.out.println("发送成功："+phone+"->"+code);
            return Result.ok();
        } else {
            return Result.error().message("发送验证码失败！");
        }
    }

    /**
     * 执行发送验证码
     *
     * @param param
     * @param phone
     * @return
     */
    public boolean send(Map<String, Object> param, String phone) {
        if (StringUtils.isEmpty(phone)) {
            return false;
        }

        String accessKeyId = ConstantConfig.END_KEYID;
        String accessKeySecret = ConstantConfig.END_KEYSECRET;
        String signName = ConstantConfig.END_SIGNNAME;
        String templateCode = ConstantConfig.END_TEMPLATECODE;

        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessKeySecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");

        //手机号
        request.putQueryParameter("PhoneNumbers", phone);
        //签名名称
        request.putQueryParameter("SignName", "iEnglish学习平台");
        //模板code
        request.putQueryParameter("TemplateCode", templateCode);
        //验证码
        request.putQueryParameter("TemplateParam", JSONObject.toJSONString(param));

        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            return response.getHttpResponse().isSuccess();
        } catch (ClientException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 校验验证码
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public Result checkCode(String phone, String code) {
        //在redis中获取验证码
        String redisCode = redisTemplate.opsForValue().get(phone);

        if (StringUtils.isEmpty(code)) {
            return Result.error();
        }

        if (Objects.equals(redisCode, code)) {
            return Result.ok().data("isTrue", true);
        }

        return Result.error();
    }
}